//手写 new 操作符实现
// 1.首先创建了一个新的空对象
// 2.设置原型，将对象的原型设置为函数的prototype对象。
// 3.让函数的this指向这个对象，执行构造函数的代码（为这个新对象添加属性）
// 4.判断函数的返回值类型，如果是值类型，返回创建的对象。如果是引用类型，就返回这个引用类型的对象。
function myNew(fn, ...args) {
    //1.创建一个空对象
    let obj = {}
    //2.空对象的__proto__ 指向构造函数的 prototype,为这个新对象添加属性
    obj.__proto__ = fn.prototype
    //3、构造函数的作用域赋值给新对象
    var res = fn.apply(obj, args)
    console.log("结果", res);
    //4、返回新对象，如果没有显示return语句，则返回this
    //基本数据类型==>仍然是实例this
    //复杂数据类型==>返回对象本身
    return Object.prototype.toString.call(res) === '[object Object]' ? res : obj
}


function myNew1(constructor, ...args) {
    //1.创建空对象，并继承构造函数constructor的原型
    let obj = Object.create(constructor.prototype)
    //2、执行构造函数，并将obj作为this执行
    const res = constructor.apply(obj, args)
    //3.返回新对象，如果没有显示return语句 则返回this
    //基本数据类型 ==>仍然返回实例this
    //复查数据类型 ==>返回对象本身

    return Object.prototype.toString.call(res) === "[object Object]" ? res : obj
}


//连环问
//{ } 创建空对象，原型指向Object.prototype
//Object.create()创建空对象，原型指向传入的参数

function test(name) {
    this.name = name
}

let me = myNew(test, '李兵')
// let me1 = new test('李兵1')

console.log(me);
// console.log(me1);


let fn = () => { }
let fn1 = {}
console.log("==>jjj", Object.prototype.toString.call(fn))
console.log("==>jjj", Object.prototype.toString.call(fn1))